<?php

class access_processor extends sharpobj_processor
{
    

    
    
    // *****************************************
    // Права
    
    /**
     * Проверяем права доступа
     *
     * @param access_data_permission $obj
     * @return bool
     */
    protected function act_isAccess(access_data_permission $obj)
    {    
        // Преобразуем именованный объект в item
        $obj = $this->act_convNamed2Item($obj);

        /*
		// Кеш прав доступа
        static $acache;
        // Проверяем попадания в локальный кеш прав доступа
        if (isset($acache[$obj->getP('subj_type')][$obj->getP('subj_id')][$obj->getP('item_type')][$obj->getP('item_id')][$obj->getP('do')]))
        {
            return $acache[$obj->getP('subj_type')][$obj->getP('subj_id')][$obj->getP('item_type')][$obj->getP('item_id')][$obj->getP('do')]; 
        }else
        {
            $cache_res = &$acache[$obj->getP('subj_type')][$obj->getP('subj_id')][$obj->getP('item_type')][$obj->getP('item_id')][$obj->getP('do')];
        }
		*/
        //print_r($obj->getP());
        // Проверяем индивидуальные права доступа
        if ($this->act_isPermission($obj)===true)
        {
            $cache_res = true;
            return true;
        }

        // Для пользователей, проверяем права в группе
        if ($obj->get('plain','subj_type')==='user')
        {
            if($this->act_isPermissionGroup($obj))
            {
                $cache_res = true;
                return true;
            }
        }

        // Проверяем, разрешено ли пользователю "что угодно"
        if (!($obj->getP('code')=='anyone' AND $obj->isNull('mod')))
        {    // Если действие не для "любого" объекта - проверяем сперва разрешено ли оно для любого
            $obj2 = clone $obj;
            $obj2->dsetNamedObj(null,'anyone');
            if ($this->act_isAccess($obj2)===true)
            {
                $cache_res = true;
                return true;
            }
        }
        $cache_res = false;
        return false;
    }
    
    /**
     * Сохранение настроек доступа для объекта
     *
     * @param sharpobj_data_interface_item $obj
     * @return int
     */
    protected function act_savePermission(sharpobj_data_interface_item $obj)
    {
        // Ищем разрешения для этого объекта в базе
        if ($obj2 = $this->act_getPermission($obj))
        {
            // Переустанавливаем id и обновляем запись
            $obj->setId($obj2->getId());
            
            // Проверяем, есть ли хотя бы одно разрешение, иначе запись можно совсем удалить
            $all_permissions = access_const_permissions();
            $delete=true;
            foreach ($all_permissions as $perm_name)
            {
                if ($obj->getP($perm_name)>0)
                {
                    $delete=false;
                }
            }
            if($delete)
            {    // Разрешений нет, поэтому запись можно просто удалить
                $this->storageLink('permissions')->delete($obj);                
            }else
            {    // Обновляем запись
                $this->storageLink('permissions')->update($obj);
            }
            // Возворазаем id
            return sharpobj_conv_int_obj($obj->getId());
        }else
        {
            return $this->storageLink('permissions')->insert($obj);
        }
    }
    
    /**
     * Получить разрешения для объекта, установленные для конкретного субьекта
     *
     * @param access_data_permission $obj
     * @return unknown
     */
    protected function act_getPermission(sharpobj_data_interface_item $obj)
    {
        $sql = " WHERE `item_type`='{$obj->get('sql','item_type')}'"
						." AND `item_id`='{$obj->get('sql','item_id')}'"
						." AND `subj_type`='{$obj->get('sql','subj_type')}'"
						." AND `subj_id`='{$obj->get('sql','subj_id')}'";
        return $this->storageLink('permissions')->sqlqueryGet($sql);
    }

    /**
     * Проверить доступ субъекта к объекту
     *
     * @param access_data_permission $obj
     * @return unknown
     */
    protected function act_isPermission(access_data_permission $obj)
    {
        // Проверяем действие
        $sql_do = $this->pvtact_do2sql($obj->get('plain','do'));
        if ($sql_do===false){return false;}
        return $this->storageLink('permissions')->sqlqueryOneValue(
						"SELECT COUNT(*) FROM #!table# "
						." WHERE `item_type`='{$obj->get('sql','item_type')}'"
						." AND `item_id`='{$obj->get('sql','item_id')}'"
						." AND `subj_type`='{$obj->get('sql','subj_type')}'"
						." AND `subj_id`='{$obj->get('sql','subj_id')}'"
						." AND {$sql_do}")>0;
    }
    
    /**
     * Проверить доступ пользователя к объекту с учетом групп
     *
     * @param access_data_permission $obj
     * @return bool
     */
    protected function act_isPermissionGroup(access_data_permission $obj)
    {
        // Проверяем действие
        $sql_do = $this->pvtact_do2sql($obj->get('plain','do'));
        if ($obj->get('plain','subj_type')!=='user')
        {
            mst_error("Неверный тип субъекта","Проверка прав в группе возможно только для пользователй",2);
            return false;
        }
        if ($sql_do===false){return false;}
        return $this->storageLink('permissions')->sqlqueryOneValue(
						"SELECT COUNT(*) FROM #!table#, `access_groupmemb`"
						." WHERE `access_groupmemb`.`usr_id`='{$obj->get('sql','subj_id')}'"
						." AND `access_groupmemb`.`group_id`=#!table#.`subj_id`"
                        ." AND `subj_type`='group'"
						." AND `item_type`='{$obj->get('sql','item_type')}'"
						." AND `item_id`='{$obj->get('sql','item_id')}'"
						." AND {$sql_do}")>0;
    }
    
    // *****************************************
    // Группы

    protected function act_saveUser2Group(sharpobj_data_interface_item $obj)
    {
        if ($this->act_isGroupMember($obj)===false)
        {
            // Пользователь еще не член группы
            return $this->storageLink('groupmemb')->insert($obj);
        }
        return true;
    }
    /**
     * Удаляем студента из группы (по usr_id и group_id
     */
    protected function act_deleteUserFromGroup(sharpobj_data_interface_item $obj)
    {
       // Удаляем членство в группах
        return $this->storageLink('groupmemb')->sqlqueryAction("DELETE FROM #!table# "
									." WHERE `usr_id`='{$obj->get('sql','usr_id')}'"
						            ." AND `group_id`='{$obj->get('sql','group_id')}'"
						            ." LIMIT 1");
    }
    /**
     * Получение id группы
     *
     * @param sharpobj_data_interface_item $obj
     * @return int
     */
    protected function act_getGroupId(sharpobj_data_interface_item $obj)
    {
        $mod_sql = '';
        if ($obj->isNull('mod'))
        {    // Модуль не указан
            $mod_sql = " `mod` IS NULL ";
        }else
        {
            $mod_sql = " `mod`='{$obj->get('sql','mod')}' ";
        }
        return (int) $this->storageLink('groups')->sqlqueryOneValue(
						"SELECT #!id# FROM #!table# "
						." WHERE {$mod_sql} "
						." AND `code`='{$obj->get('sql','code')}'");
    }
    /**
     * Является ли пользователь членом группы
     */
    protected function act_isGroupMember(sharpobj_data_interface_item $obj)
    {
        // Проверяем действие
        return $this->storageLink('groupmemb')->sqlqueryOneValue(
						"SELECT COUNT(*) FROM #!table# "
						." WHERE `usr_id`='{$obj->get('sql','usr_id')}'"
						." AND `group_id`='{$obj->get('sql','group_id')}'")>0;
    }
    
    
    // *****************************************
    // Роли
    
    /**
     * Присвоена ли пользователю роль
     */
    protected function act_isRoleMember(sharpobj_data_interface_item $obj)
    {
        // Проверяем действие
        return $this->storageLink('rolememb')->sqlqueryOneValue(
						"SELECT COUNT(*) FROM #!table# "
						." WHERE `usr_id`='{$obj->get('sql','usr_id')}'"
						." AND `role_id`='{$obj->get('sql','role_id')}'")>0;
    } 
    /*
     * Назначаем пользователю роль, если еще не назначено
     */
    protected function act_saveUser2RoleId(sharpobj_data_interface_item $obj)
    {
        if ($this->act_isRoleMember($obj)===false)
        {
            // Пользователь еще не член группы
            return $this->storageLink('rolememb')->insert($obj);
        }else
        {
            $obj2 = $this->act_getRoleMemb($obj);
            $obj2->setP($obj->getP('order'),'order');
            return $this->storageLink('rolememb')->update($obj2);
        }
    }
    
    /**
     * Получение id роли
     *
     * @param sharpobj_data_interface_item $obj
     * @return int
     */
    protected function act_getRoleId(sharpobj_data_interface_item $obj)
    {
        return (int) $this->storageLink('roles')->sqlqueryOneValue(
						"SELECT #!id# FROM #!table# "
						." WHERE `mod`='{$obj->get('sql','mod')}'"
						." AND `code`='{$obj->get('sql','code')}'");
    }
    /**
     * Получение id роли
     *
     * @param sharpobj_data_interface_item $obj
     * @return int
     */
    protected function act_saveRole(sharpobj_data_interface_item $obj)
    {
        // Ищем разрешения для этого объекта в базе
        if ($obj2 = $this->act_getRoleId($obj))
        {
            return $obj2;
        }else
        {
            return $this->storageLink('roles')->insert($obj);
        }
    }
    /**
     * Получить запись о роли пользователя
     *
     * @param sharpobj_data_interface_item $obj
     * @return unknown
     */
    protected function act_getRoleMemb(sharpobj_data_interface_item $obj)
    {
        return $this->storageLink('rolememb')->sqlqueryGet(
						" WHERE `usr_id`='{$obj->get('sql','usr_id')}'"
						." AND `role_id`='{$obj->get('sql','role_id')}'");
    }
    /**
     * Получить список ролей, присвоенных поьзователю в данном модуле
     */
    protected function act_listUserRoles(sharpobj_data_interface_item $obj)
    {
        return $this->storageLink('roles')->sqlqueryList(
                        "SELECT #!id# FROM #!table#,`access_rolememb` "
						." WHERE `access_rolememb`.`role_id` = #!id#"
						."AND `usr_id`='{$obj->get('sql','usr_id')}'"
						." AND #!table#.`mod`='{$obj->get('sql','mod')}'"
						." ORDER BY `access_rolememb`.`order` ASC");
    }

    // *****************************************
    // Именованные объекты    

	/**
     * Преобразуем именованный объект в item_id и item_type
     *
     * @param access_data_permission $obj
     * @return unknown
     */
    protected function act_convNamed2Item(access_data_permission $obj)
    {
        // Ищем именованный объект
        if ($obj->isData('code'))
        {
            $id = $this->act_saveNamedItem($obj);
            /*
            $id = $this->storageLink('objnames')->sqlqueryOneValue(
						"SELECT #!id# FROM #!table# "
						." WHERE `mod`='{$obj->get('sql','mod')}'"
						." AND `code`='{$obj->get('sql','code')}'");
			*/
            if ($id and !sharpobj_iserror($id))
            {
                $obj->set('plain','obj_named','item_type');
                $obj->set('plain',$id,'item_id');
            }
        }
        return $obj;
    }
    protected function act_saveNamedItem(sharpobj_data_interface_item $obj)
    {
        // Из экономии выбираем значения один раз
        $mod = $obj->get('sql','mod');
        $code = $obj->get('sql','code');
        
        /*
        // Объявляем локальный кеш (на время исполнения)
        static $ncache;
        if (isset($ncache[$mod][$code]))
        {    // Значение есть в кеше
            return $ncache[$mod][$code];
        }else
        {
            $cache_res = &$ncache[$mod][$code];
        }
		*/
        
        $mod_sql = '';
        if ($obj->isNull('mod') OR $obj->isEmpty('mod'))
        {    // Модуль не указан
            $mod_sql = " `mod` IS NULL ";
        }else
        {
            $mod_sql = " `mod`='{$obj->get('sql','mod')}' ";
        }
        $id = $this->storageLink('objnames')->sqlqueryOneValueInt(
						"SELECT #!id# FROM #!table# "
						." WHERE {$mod_sql}"
						." AND `code`='{$obj->get('sql','code')}'");
        if ($id)
        {
            // Пополняем кеш
            $cache_res = $id;
            return $id;
            
        }
        return sharpobj_conv_obj_int($this->storageLink('objnames')->insert($obj));
    }    

    // ****************************************************
    // Удаление

    protected function act_deleteUser($usr_id)
    {
        $usr_id = sharpobj_conv_obj_int($usr_id);
        if (!$usr_id)
        {
            return false;
        }
        // Удаляем членство в группах
        $this->storageLink('groupmemb')->sqlqueryAction("DELETE FROM #!table# WHERE `usr_id`='{$usr_id}'");
        // Удаляем членство в ролях
        $this->storageLink('rolememb')->sqlqueryAction("DELETE FROM #!table# WHERE `usr_id`='{$usr_id}'");
        // Удаляем привеллегии
        $this->storageLink('permissions')->sqlqueryAction("DELETE FROM #!table# WHERE `subj_type`='user' AND `subj_id`='{$usr_id}'");
        return true;
    }
    protected function act_deleteGroup($group_id)
    {
        $group_id = sharpobj_conv_int_obj($group_id);
        if (!$group_id)
        {
            return false;
        }
        // Удаляем членство в группах
        $this->storageLink('groupmemb')->sqlqueryAction("DELETE FROM #!table# WHERE `group_id`='{$group_id->get('sql')}'");
        // Удаляем привеллегии
        $this->storageLink('permissions')->sqlqueryAction("DELETE FROM #!table# WHERE `subj_type`='group' AND `subj_id`='{$group_id->get('sql')}'");
        // Удаляем группу
        $this->storageLink('groups')->delete($group_id);        
        return true;
    }
    /**
     * Удаление прав на объект или именованного объекта, вместе со всеми упоминаниями
     */
    protected function act_deleteItem(access_data_permission $obj)
    {
        if ($obj->getP('item_type')==='obj_named' AND $obj->isData('code'))
        {
              $item_id = $this->act_saveNamedItem($obj);
              $item_type = 'obj_named';
              // Удаляем сам именованный объект
              $this->storageLink('objnames')->delete($item_id);
        }else
        {
            $item_id = $obj->get('sql','item_id');
            $item_type = $obj->get('sql','item_type');
        }
        // Удаляем привеллегии
        $this->storageLink('permissions')->sqlqueryAction("DELETE FROM #!table# WHERE "
                    ."`item_type`='{$item_type}' AND `item_id`='{$item_id}'");
        return true;
    }

    // ****************************************************
    // Утилиты
    
    protected function pvtact_do2sql($do)
    {
        $sql_do = '';
        switch ($do)
        {
            case 'view':
                $sql_do ="`view`='1'"; 
            break;
            case 'read':
                $sql_do ="`read`='1'"; 
            break;
            case 'modify':
                $sql_do ="`modify`='1'"; 
            break;
            case 'delete':
                $sql_do ="`delete`='1'"; 
            break;
            case 'create':
                $sql_do ="`create`='1'"; 
            break;
            case 'own':
                $sql_do ="`own`='1'"; 
            break;
            case 'exec':
                $sql_do ="`exec`='1'"; 
            break;
            default:
                mst_error("Неправильное действие","Разрешения для действия ({$do}) не предусмотрены",2);
                return false;
            break;
        }
        return $sql_do;
    }
    // ***********************************************
    // Инициализация
    
    // Исталляция
    protected function act_createTables()
    {
        //
        $this->storageLink('permissions')->sqlqueryAction("CREATE TABLE #!table# (
 `id` int(11) NOT NULL auto_increment,
 `item_type` enum('obj_named','obj','obj_class','obj_category','group')
collate utf8_unicode_ci default NULL,
 `item_id` int(11) NOT NULL,
 `subj_type` enum('user','group') collate utf8_unicode_ci default NULL,
 `subj_id` int(11) NOT NULL,
 `view` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 `read` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 `modify` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 `delete` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 `create` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 `exec` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 `own` enum('0','1') collate utf8_unicode_ci NOT NULL default '0',
 PRIMARY KEY  (`id`),
 KEY `items` (`item_type`,`item_id`),
 KEY `subjects` (`subj_id`,`subj_type`),
 KEY `subjects_type` (`subj_type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
COMMENT='Разрешения доступа';");

        $this->storageLink('groups')->sqlqueryAction("CREATE TABLE #!table# (
 `id` int(11) NOT NULL auto_increment,
 `code` varchar(100) collate utf8_unicode_ci default NULL,
 `mod` varchar(100) collate utf8_unicode_ci default NULL,
 `name` varchar(255) collate utf8_unicode_ci NOT NULL,
 PRIMARY KEY  (`id`),
 UNIQUE KEY `modcode` (`mod`,`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
COMMENT='Группы';");
        $this->storageLink('groupmemb')->sqlqueryAction("CREATE TABLE #!table# (
 `id` int(11) NOT NULL auto_increment,
 `usr_id` int(11) NOT NULL,
 `group_id` int(11) NOT NULL,
 PRIMARY KEY  (`id`),
 UNIQUE KEY `usr2groups` (`usr_id`,`group_id`),
	KEY `group_id` (`group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
COMMENT='членство в группах';");
        $this->storageLink('objnames')->sqlqueryAction("CREATE TABLE #!table# (
 `id` int(11) NOT NULL auto_increment,
 `mod` varchar(100) collate utf8_unicode_ci  default NULL,
 `code` varchar(100) collate utf8_unicode_ci NOT NULL,
 PRIMARY KEY  (`id`),
 UNIQUE KEY `modnames` (`mod`,`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
COMMENT='Именованные объекты в модулях';");
        $this->storageLink('roles')->sqlqueryAction("CREATE TABLE #!table# (
`id` int(11) NOT NULL auto_increment,
 `code` varchar(100) collate utf8_unicode_ci default NULL,
 `mod` varchar(100) collate utf8_unicode_ci default NULL,
 `name` varchar(255) collate utf8_unicode_ci NOT NULL,
 PRIMARY KEY  (`id`),
 UNIQUE KEY `modcode` (`mod`,`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
COMMENT='Роли';");
        $this->storageLink('rolememb')->sqlqueryAction("CREATE TABLE #!table# (
  `id` int(11) NOT NULL auto_increment,
 `usr_id` int(11) NOT NULL,
 `role_id` int(11) NOT NULL,
 `order` int(11) NOT NULL,
 PRIMARY KEY  (`id`),
 KEY `usr_id` (`usr_id`),
 KEY `role_id` (`role_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
COMMENT='Роли пользователей';");   
    }
    protected function act_dropTables()
    {
        //
        $this->storageLink('permissions')->sqlqueryAction("DROP TABLE #!table#;");
        $this->storageLink('groups')->sqlqueryAction("DROP TABLE #!table#;");
        $this->storageLink('groupmemb')->sqlqueryAction("DROP TABLE #!table#;");
        $this->storageLink('objnames')->sqlqueryAction("DROP TABLE #!table#;");
        $this->storageLink('roles')->sqlqueryAction("DROP TABLE #!table#;");
        $this->storageLink('rolememb')->sqlqueryAction("DROP TABLE #!table#;");
    }
    function __construct()
    {
        // Создаем справочники
        // Задаем формат справочников

        // ***Форма регистрации пользователей***
        // Объявляем формат
        $format_permissions = new sharpobj_storage_format();
        // Пример элемента
        $format_permissions->addItem('item_type','item_type','smallatword');
        $format_permissions->addItem('item_id','item_id','int');
        $format_permissions->addItem('subj_type','subj_type','smallatword');
        $format_permissions->addItem('subj_id','subj_id','int');
        $format_permissions->addItem('view','view','int');
        $format_permissions->addItem('read','read','int');
        $format_permissions->addItem('modify','modify','int');
        $format_permissions->addItem('delete','delete','int');
        $format_permissions->addItem('create','create','int');
        $format_permissions->addItem('exec','exec','int');
        $format_permissions->addItem('own','own','int');

        /* Объявляем справочники */
        // Объявляем справочник
        $this->storageAdd
                        (
							'permissions', 
                            new sharpobj_storage_mysql
                            (
                                $format_permissions,
                                array(
										'tbname'=>'access_permissions',
										'idfield'=>'id'
                                      )
                            )
                        );
        // Объявляем формат
        $format_groups = new sharpobj_storage_format();
        // Пример элемента
        $format_groups->addItem('code','code','smallatword',array('len_max'=>50));
        $format_groups->addItem('mod','mod','smallatword',array('len_max'=>50));
        $format_groups->addItem('name','name','row',array('len_max'=>250));
        // Объявляем справочник
        $this->storageAdd
                        (
							'groups', 
                            new sharpobj_storage_mysql
                            (
                                $format_groups,
                                array(
										'tbname'=>'access_groups',
										'idfield'=>'id'
                                      )
                            )
                        );
        // Объявляем формат
        $format_groupmemb = new sharpobj_storage_format();
        // Пример элемента
        $format_groupmemb->addItem('usr_id','usr_id','int');
        $format_groupmemb->addItem('group_id','group_id','int');
        // Объявляем справочник
        $this->storageAdd
                        (
							'groupmemb', 
                            new sharpobj_storage_mysql
                            (
                                $format_groupmemb,
                                array(
										'tbname'=>'access_groupmemb',
										'idfield'=>'id'
                                      )
                            )
                        );
        // Объявляем формат
        $format_objnames = new sharpobj_storage_format();
        // Пример элемента
        $format_objnames->addItem('mod','mod','smallatword',array('len_max'=>50));
        $format_objnames->addItem('code','code','smallatword',array('len_max'=>50));
        
        // Объявляем справочник
        $this->storageAdd
                        (
							'objnames', 
                            new sharpobj_storage_mysql
                            (
                                $format_objnames,
                                array(
										'tbname'=>'access_objnames',
										'idfield'=>'id'
                                      )
                            )
                        );
        // Объявляем формат
        $format_roles = new sharpobj_storage_format();
        // Пример элемента
        $format_roles->addItem('code','code','smallatword',array('len_max'=>50));
        $format_roles->addItem('mod','mod','smallatword',array('len_max'=>50));
        $format_roles->addItem('name','name','row',array('len_max'=>250));
        // Объявляем справочник
        $this->storageAdd
                        (
							'roles', 
                            new sharpobj_storage_mysql
                            (
                                $format_roles,
                                array(
										'tbname'=>'access_roles',
										'idfield'=>'id'
                                      )
                            )
                        );
        // Объявляем формат
        $format_rolememb = new sharpobj_storage_format();
        // Пример элемента
        $format_rolememb->addItem('usr_id','usr_id','int');
        $format_rolememb->addItem('role_id','role_id','int');
        $format_rolememb->addItem('order','order','int');
        // Объявляем справочник
        $this->storageAdd
                        (
							'rolememb', 
                            new sharpobj_storage_mysql
                            (
                                $format_rolememb,
                                array(
										'tbname'=>'access_rolememb',
										'idfield'=>'id'
                                      )
                            )
                        );
        // *******************************************************
        // Форматы объектов
                        
    }
}


// *********************************************
// Утилиты
/*
 * Информация для проверки прав доступа
 */
class access_data_permission extends sharpobj_data_item_data 
{
	//
    function __construct()
    {
    	$options=null;
        parent::__construct($options);
        $this->addItem('item_type','smallatword');
        $this->addItem('item_id','int');

        $this->addItem('mod','smallatword');
        $this->addItem('code','smallatword');
        
        $this->addItem('subj_type','smallatword');
        $this->addItem('subj_id','int');
        $this->addItem('usr_id','int');
        
        $this->addItem('do','smallatword');


    }
    
    function dsetUser($usr_id)
    {
        $this->set('plain','user','subj_type');
        $this->set('plain',$usr_id,'subj_id');
        $this->set('plain',$usr_id,'usr_id');
    }
    function dsetGroup($group_id)
    {
        $this->set('plain','group','subj_type');
        $this->set('plain',$group_id,'subj_id');
    }
    function dsetItem($item_type,$item_id)
    {
        $this->set('plain',$item_type,'item_type');
        $this->set('plain',$item_id,'item_id');
    }
    function dsetNamedObj($mod,$code)
    {
        $this->set('plain','obj_named','item_type');
        $this->set('plain',$mod,'mod');
        $this->set('plain',$code,'code');
    }
    function dsetDo($do)
    {
        $this->set('plain',$do,'do');
    }

}
?>